using Gateway.Common.Enums;
using Gateway.Domain.Entities;
using Gateway.IApplication.UserMessage;
using Gateway.IApplication.UserMessage.Input;
using Gateway.IRepositories;
using Microsoft.EntityFrameworkCore;

namespace Gateway.Application;

/// <summary>
/// user message 
/// </summary>
public class UserMessageApp : IUserMessageApp
{
    private readonly IAppRepository<UserMessage> _repository;
    private readonly IAppRepository<UserClient> _clientRepository;
    private readonly IUnitOfWork _unitOfWork;
    /// <summary>
    /// 
    /// </summary>
    /// <param name="repository"></param>
    /// <param name="clientRepository"></param>
    /// <param name="unitOfWork"></param>
    public UserMessageApp(IAppRepository<UserMessage> repository,
        IAppRepository<UserClient> clientRepository, IUnitOfWork unitOfWork)
    {
        _repository = repository;
        _clientRepository = clientRepository;
        _unitOfWork = unitOfWork;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="connectionId"></param>
    /// <param name="account"></param>
    /// <returns></returns>
    public async Task<bool> CreateClient(string connectionId, string account)
    {
        var entity = new UserClient(connectionId: connectionId, account: account);
        await _clientRepository.AddAsync(entity);
        await _unitOfWork.CommitAsync();
        return true;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="account"></param>
    /// <returns></returns>
    public async Task<List<string>> GetConnectionIdByAccount(string account)
    {
        var data = await _clientRepository.GetListAsync(x => x.Account.Equals(account));
        return data.Select(x => x.ConnectionId).ToList();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="userId"></param>
    /// <returns></returns>
    public async Task<bool> ReadAll(string userId)
    {
        var data = await _repository.GetListAsync(x =>
            x.Account.Equals(userId) && x.ReadStatus == BooleanStatusEnum.No);
        foreach (var userMessage in data)
        {
            userMessage.ReadStatus = BooleanStatusEnum.Yes;
            await _repository.UpdateAsync(userMessage);
        }
        await _unitOfWork.CommitAsync();
        return true;
    }
    /// <summary>
    /// 删除长时间不使用的
    /// </summary>
    /// <returns></returns>
    public async Task<bool> RemoveLongTimeNoUse()
    {
        var entities =
            await _clientRepository.Entities.IgnoreQueryFilters()
                .Where(x =>
                    x.CreatedTime < (DateTime.Now.AddDays(-3)))
                .ToListAsync();
        if (entities.Count > 0)
        {
            foreach (var item in entities)
            {
                await _clientRepository.DeleteAsync(item);
            }

            await _unitOfWork.CommitAsync();
        }

        return true;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<string> CreateTask(CreateUserTaskInput input)
    {
        var message = new UserMessage(account: input.Account,
            message: input.TaskName,
            sendType: SendTypeEnum.Person.Value,
            sender: input.Account,
            messageType: MessageTypeEnum.Task.Value,
            state: MessageStateEnum.Doing.Value,
            resourceId: input.ResourceId);
        await _repository.AddAsync(message);
        await _unitOfWork.CommitAsync();
        return message.Id;
    }
    /// <summary>
    /// 设置任务结果
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task SetTaskResult(SetTaskResultInput input)
    {
        var data = await _repository.FirstOrDefaultAsync(x => x.Id.Equals(input.TaskId));
        if (data == null)
            return;
        data.SetResult(input.State, input.Result, input.Message);
        await _repository.UpdateAsync(data);
        await _unitOfWork.CommitAsync();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="account"></param>
    /// <param name="connectionId"></param>
    /// <returns></returns>
    public async Task<bool> RemoveClient(string account, string connectionId)
    {
        var entity =
            await _clientRepository.FirstOrDefaultAsync(x =>
                x.Account.Equals(account) && x.ConnectionId.Equals(connectionId));
        if (entity != null)
        {
            await _clientRepository.DeleteAsync(entity);
            await _unitOfWork.CommitAsync();
        }

        return true;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<string> CreateMessage(CreateUserMessageInput input)
    {
        var message = new UserMessage(account: input.Account, message: input.Message,
            sendType: input.SendType.Value,
            sender: input.Sender);
        await _repository.AddAsync(message);
        await _unitOfWork.CommitAsync();
        return message.Id;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="messageId"></param>
    /// <returns></returns>
    public async Task<bool> Read(string messageId)
    {
        var message = await _repository.FirstOrDefaultAsync(x => x.Id.Equals(messageId));
        if (message != null)
        {
            message.Read();
            await _repository.UpdateAsync(message);
            await _unitOfWork.CommitAsync();
        }

        return true;
    }
}